home *** CD-ROM | disk | FTP | other *** search
/ Chip 1996 September / CHIP Eylül 1996.iso / utils / povray / povppc.sit / POVPPC / SOURCE / SaveCmpPict.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-25  |  13.6 KB  |  464 lines

  1. /*
  2. ==============================================================================
  3. Project:    POV-Ray
  4.  
  5. Version:    2.2
  6.  
  7. File Name:    SaveCmpPict.c
  8.  
  9. Description:
  10.     Routines for saving a PICT file in QuickTime compressed format.
  11.     
  12.     This source code was written with a lot of help from some examples
  13.     off of Apple's QuickTime 1.0 Developer CD.
  14.  
  15.     Note that this source requires the as-yet non-standard header files
  16.     and glue files for QuickTime and the Standard Compression dialog.
  17.     These files will need to accompany this source until Apple rolls them
  18.     into MPW/Think.  The files needed are listed below:
  19.     Components.h            - MPW/Think - QuickTime Component header
  20.     ImageCompression.h        - MPW/Think - QuickTime Image Compression header
  21.     StdCompression.h        - MPW/Think - Std Compression dialog header
  22.     StdCompression.rsrc        - MPW/Think - Std Compression dialog resource
  23.     StdCompressionGlue.o    - MPW - Std Compression dialog glue routines
  24.     StdCompressionGlue.╣    - Think - Std Compression dialog glue routines
  25.  
  26. Related Files:
  27.     SaveCmpPict.h: header file for Save Compressed Pict routines
  28.     SaveCmpPict.c: main file for Save Compressed Pict routines
  29. ------------------------------------------------------------------------------
  30. Author:
  31.     Eduard [esp] Schwan
  32. ------------------------------------------------------------------------------
  33.     from Persistence of Vision Raytracer
  34.     Copyright 1993 Persistence of Vision Team
  35. ------------------------------------------------------------------------------
  36.     NOTICE: This source code file is provided so that users may experiment
  37.     with enhancements to POV-Ray and to port the software to platforms other 
  38.     than those supported by the POV-Ray Team.  There are strict rules under
  39.     which you are permitted to use this file.  The rules are in the file
  40.     named POVLEGAL.DOC which should be distributed with this file. If 
  41.     POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  42.     Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  43.     Forum.  The latest version of POV-Ray may be found there as well.
  44.  
  45.     This program is based on the popular DKB raytracer version 2.12.
  46.     DKBTrace was originally written by David K. Buck.
  47.     DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  48. ------------------------------------------------------------------------------
  49. More Info:
  50.     This Macintosh version of POV-Ray was created and compiled by Jim Nitchals
  51.     (Think 5.0) and Eduard Schwan (MPW 3.2), based (loosely) on the original
  52.     port by Thomas Okken and David Lichtman, with some help from Glenn Sugden.
  53.  
  54.     For bug reports regarding the Macintosh version, you should contact:
  55.     Eduard [esp] Schwan
  56.         CompuServe: 71513,2161
  57.         Internet: jl.tech@applelink.apple.com
  58.         AppleLink: jl.tech
  59.     Jim Nitchals
  60.         Compuserve: 73117,3020
  61.         America Online: JIMN8
  62.         Internet: jimn8@aol.com -or- jimn8@applelink.apple.com
  63.         AppleLink: JIMN8
  64. ------------------------------------------------------------------------------
  65. Change History:
  66.     920414    [esp]    Created.
  67.     920418    [esp]    Broke routines into UI and non-UI components for later factoring
  68.     920419    [esp]    Embellished file header comments, renamed routines for consistency
  69.     920611    [esp]    Worked on AppendFinderIcons2PictF function
  70.     930526    [esp]    Updated SC dialog & Compression calls for QT 1.5
  71.     931001    [esp]    version 2.0 finished (Released on 10/4/93)
  72. ==============================================================================
  73. */
  74.  
  75.  
  76. /*==== Headers ====*/
  77.  
  78. #include "SaveCmpPict.h"
  79.  
  80. #include <errors.h>        // dupFNErr
  81. #include <finder.h>        // for kCustomIconResource
  82. #include <resources.h>
  83. #include <icons.h>        // for large1BitMask etc.
  84.  
  85.  
  86. /*
  87. ******************************************************************************
  88. Name:
  89.     AppendFilePreview2PictF
  90. ------------------------------------------------------------------------------
  91. Purpose:
  92.     Create a preview image for users of QuickTime¬ standard File preview.
  93. ------------------------------------------------------------------------------
  94. Description:
  95.     ** How it does it
  96. ------------------------------------------------------------------------------
  97. Parameters:
  98. ------------------------------------------------------------------------------
  99. When Used:
  100.     ** who calls me and why/when
  101. ******************************************************************************
  102. */
  103. OSErr AppendFilePreview2PictF(FSSpec *fsFile)
  104. {
  105.     OSErr    anError = noErr;
  106.     short    fileResRef;
  107.  
  108.     fileResRef = FSpOpenResFile(fsFile, fsRdWrPerm);
  109.     anError = ResError();
  110.  
  111.     if (!anError && (fileResRef != -1))
  112.     {
  113.         anError = MakeFilePreview(fileResRef, (ICMProgressProcRecordPtr)-1);
  114.         CloseResFile(fileResRef);
  115.     }
  116.     return anError;
  117. } // AppendFilePreview2PictF
  118.  
  119.  
  120. /*
  121. ******************************************************************************
  122. Name:
  123.     AppendFinderIcons2PictF
  124. ------------------------------------------------------------------------------
  125. Purpose:
  126.     Embed custom icons in file, for System 7.0 users to see from the Finder.
  127. ------------------------------------------------------------------------------
  128. Description:
  129.     ** How it does it
  130. ------------------------------------------------------------------------------
  131. Parameters:
  132. ------------------------------------------------------------------------------
  133. When Used:
  134.     ** who calls me and why/when
  135. ******************************************************************************
  136. */
  137. OSErr AppendFinderIcons2PictF(FSSpec *fsFile,
  138.                         Rect *theOriginalPicFrame,
  139.                         eAFI_ImagePrefs_t theImagePrefs)
  140. {    
  141.     OSErr        anError;
  142.     GWorldPtr    iconGWorld = NULL,
  143.                 imageWorld = NULL;
  144.     short        oldResFile;
  145.     Rect        irect,
  146.                 orect,
  147.                 maxRect;
  148.     Handle        tmpHandle;
  149.     Handle        destIconRsrc;
  150.     short        rowBytes,
  151.                 theWidth,
  152.                 theHeight,
  153.                 theDepth,
  154.                 iconCounter;
  155.     char        mmumode;
  156.     signed char theCorner;
  157.     short        i,j;
  158.     Ptr            srcPixPtr,
  159.                 tempDestPixPtr,
  160.                 tempSrcPixPtr;
  161.     short        bytesPerRow;
  162.     short        theSize;
  163.     OSType        theRsrcType;
  164.     FInfo        finfo;
  165.     short        fileRef;
  166.  
  167.     oldResFile = CurResFile();    // remember old file
  168.  
  169.     // Create a GWorld to hold the 32x32 image from which to copy..
  170.     SetRect(&orect, 0, 0, 32, 32);
  171.     anError = NewGWorld(&imageWorld, 32, &orect, (CTabHandle)NULL, (GDHandle)NULL, (GWorldFlags)0);
  172.  
  173.     if (!anError)
  174.     {
  175.         SetGWorld(imageWorld, (GDHandle)NULL);
  176.         EraseRect(&orect);
  177.         maxRect = irect = *theOriginalPicFrame;
  178.         theWidth = irect.right - irect.left;
  179.         theHeight = irect.bottom - irect.top;
  180.  
  181.         // Figure out the source rectangle
  182.         switch (theImagePrefs)
  183.         {
  184.         case eAFI_ShrinkWholeImage:
  185.             /* this saves the whole image as the icon */
  186.             irect = orect;    // shrink down to 32x32
  187.             break;
  188.         case eAFI_UseCenter:
  189.             /* Questionable code.. need to scrutinize this! Not that I don't trust MacDTS..*/
  190.             /* this takes a square from the center of the image */
  191.             if (theWidth > theHeight) 
  192.                 maxRect.right = maxRect.left + theHeight;
  193.              else 
  194.                 maxRect.bottom = maxRect.top + theWidth;
  195.             MapRect(&irect, &maxRect, &orect);
  196.             theWidth = 32 - (irect.right - irect.left);
  197.             theHeight = 32 - (irect.bottom - irect.top);
  198.             OffsetRect(&irect, theWidth>>1, theHeight>>1);
  199.             break;
  200.         } // switch
  201.     }
  202.  
  203.     // Draw the image into the GWorld
  204.     if (!anError)
  205.         anError = FSpOpenDF(fsFile, fsRdPerm, &fileRef);
  206.     if (!anError)
  207.     {
  208.         anError = DrawPictureFile(fileRef, &irect, NULL);
  209.         FSClose(fileRef);
  210.     }
  211.  
  212.     // now going from 32x32 input image
  213.     irect = orect;
  214.  
  215.     // Create/Open resource fork, in order to add icl resources
  216.     fileRef = kRsrcFileClosed;
  217.     if (!anError)
  218.     {
  219.         FSpCreateResFile(fsFile, 'ttxt','PICT', (ScriptCode)0);
  220.         anError = ResError();
  221.         if (!anError)
  222.         {
  223.             fileRef = FSpOpenResFile(fsFile, fsRdWrPerm);
  224.             anError = ResError();
  225.         }
  226.     }
  227.  
  228.     // loop through each icon depth
  229.     if (!anError)
  230.     { // if opened ok
  231.         for (iconCounter=1; iconCounter <= 6 && !anError; iconCounter++)
  232.         {
  233.             switch(iconCounter)
  234.             {
  235.             case 1:
  236.                 theRsrcType = large1BitMask;
  237.                 theWidth = 32;
  238.                 theHeight = 32;
  239.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  240.                 theDepth = 1;
  241.                 bytesPerRow = 4;
  242.                 theSize = theHeight*bytesPerRow*2;    // x2 'cause icon+mask
  243.                 break;
  244.             case 2:
  245.                 theRsrcType = large4BitData;
  246.                 theWidth = 32;
  247.                 theHeight = 32;
  248.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  249.                 theDepth = 4;
  250.                 bytesPerRow = 16;
  251.                 theSize = theHeight*bytesPerRow;
  252.                 break;
  253.             case 3:
  254.                 theRsrcType = large8BitData;
  255.                 theWidth = 32;
  256.                 theHeight = 32;
  257.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  258.                 theDepth = 8;
  259.                 bytesPerRow = 32;
  260.                 theSize = theHeight*bytesPerRow;
  261.                 break;
  262.             case 4:
  263.                 theRsrcType = small1BitMask;
  264.                 theWidth = 16;
  265.                 theHeight = 16;
  266.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  267.                 theDepth = 1;
  268.                 bytesPerRow = 2;
  269.                 theSize = theHeight*bytesPerRow*2;    // x2 'cause icon+mask
  270.                 break;
  271.             case 5:
  272.                 theRsrcType = small4BitData;
  273.                 theWidth = 16;
  274.                 theHeight = 16;
  275.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  276.                 theDepth = 4;
  277.                 bytesPerRow = 8;
  278.                 theSize = theHeight*bytesPerRow;
  279.                 break;
  280.             case 6:
  281.                 theRsrcType = small8BitData;
  282.                 theWidth = 16;
  283.                 theHeight = 16;
  284.                 SetRect(&orect, 0, 0, theWidth, theHeight);
  285.                 theDepth = 8;
  286.                 bytesPerRow = 16;
  287.                 theSize = theHeight*bytesPerRow;
  288.                 break;
  289.             } // switch
  290.     
  291.             anError = NewGWorld(&iconGWorld, theDepth, &orect, (CTabHandle)NULL, (GDHandle)NULL, (GWorldFlags)0);
  292.             if (!anError)
  293.             {
  294.                 SetGWorld(iconGWorld, (GDHandle)NULL);
  295.                 LockPixels(iconGWorld->portPixMap);
  296.                 // put the image into the destination (iconWorld)
  297.                 CopyBits((BitMap *)*imageWorld->portPixMap,
  298.                         (BitMap *)*iconGWorld->portPixMap,
  299.                         &irect, &orect,
  300.                         ditherCopy, NULL);
  301.  
  302.                 // Draw border and folded document corner on iconWorld
  303.                 if (!anError)
  304.                 {
  305.                     // outer border
  306.                     FrameRect(&orect);
  307.                     // upper folded corner
  308.                     SetRect(&maxRect,((theWidth*3)/4)+1,-1,theWidth+1,(theHeight>>2)-1);
  309.                     // erase upper corner to white
  310.                     EraseRect(&maxRect);
  311.                     // draw lower folded corner
  312.                     FrameRect(&maxRect);
  313.                     // draw diagonal line
  314.                     MoveTo(((theWidth*3)/4)+1, 0);
  315.                     LineTo(theWidth, (theHeight>>2)-1);
  316.                 }
  317.  
  318.                 if ((destIconRsrc=NewHandle(theSize)) != NULL)
  319.                 {
  320.                     HLock(destIconRsrc);
  321.                     rowBytes = (*iconGWorld->portPixMap)->rowBytes & 0x3fff;
  322.                     srcPixPtr = GetPixBaseAddr(iconGWorld->portPixMap);
  323.                     tempDestPixPtr = StripAddress(*destIconRsrc);
  324.                     mmumode = true32b;
  325.                     SwapMMUMode(&mmumode);    // into 32 bit mode
  326.                     for (i=0; i < orect.bottom; i++)
  327.                     {
  328.                         tempSrcPixPtr = srcPixPtr;
  329.                         for (j=0; j < bytesPerRow; j++) 
  330.                             *tempDestPixPtr++ = *tempSrcPixPtr++;
  331.                         srcPixPtr += rowBytes;
  332.                     }
  333.                     // in 1 bit depth, fill the icon mask too
  334.                     if (theDepth == 1)
  335.                     {
  336.                         if (bytesPerRow <= 2)
  337.                             theCorner = 0xfC;    // small corner (1111 1100)
  338.                         else
  339.                             theCorner = 0xC0;    // regular corner (1100 0000)
  340.                         for (i=0; i < orect.bottom; i++)
  341.                         {
  342.                             for (j=0; j < (bytesPerRow-1); j++) 
  343.                                 *tempDestPixPtr++ = 0xff;
  344.                             *tempDestPixPtr++ = theCorner;
  345.                             theCorner >>= 1; // roll the corner mask over slowly
  346.                         }
  347.                     }
  348.                     SwapMMUMode(&mmumode);    // restore original mode
  349.  
  350.                     // as long as there are old icon resources, delete them..
  351.                     do {
  352.                         tmpHandle = Get1Resource(theRsrcType, kCustomIconResource);
  353.                         if (tmpHandle != NULL)
  354.                         {
  355.                             RmveResource(tmpHandle);
  356.                             DisposeHandle(tmpHandle);
  357.                         }
  358.                     } while (tmpHandle != NULL);
  359.  
  360.                     HUnlock(destIconRsrc);
  361.                     AddResource(destIconRsrc, theRsrcType, kCustomIconResource, NULL);
  362.                     anError = ResError();
  363.                     if (!anError)
  364.                     {
  365.                         WriteResource(destIconRsrc);
  366. // huh?  What's this here for?  Delete this line when sure it's incorrect...
  367. //                        ReleaseResource(destIconRsrc);
  368.                     }
  369.                 }
  370.  
  371.                 if (iconGWorld)
  372.                 {
  373.                     DisposeGWorld(iconGWorld);
  374.                     iconGWorld = NULL;
  375.                 }
  376.  
  377.             }
  378.         } // for
  379.  
  380.         // Turn on the FinderInfo flag to display the custom icon suite
  381.         if (!anError)
  382.         {
  383.             UpdateResFile(fileRef);
  384.             anError = ResError();
  385.             if (!anError)
  386.                 anError = FSpGetFInfo(fsFile,&finfo);
  387.             if (!anError)
  388.             {
  389.                 finfo.fdFlags |= 1<<10;            // turn on hasCustomIcon flag
  390.                 finfo.fdFlags &= ~(1<<8);        // turn off hasBeenInited flag
  391.                 FSpSetFInfo(fsFile, &finfo);
  392.             }
  393.         }
  394.  
  395.         // close our resource file now
  396.         if (fileRef != kRsrcFileClosed)
  397.             CloseResFile(fileRef);
  398.     } // if opened ok
  399.  
  400.     UseResFile(oldResFile);
  401.  
  402.     if (iconGWorld)
  403.         DisposeGWorld(iconGWorld);
  404.     if (imageWorld)
  405.         DisposeGWorld(imageWorld);
  406.     
  407.     return anError;
  408.  
  409. } // AppendFinderIcons2PictF
  410.  
  411.  
  412.  
  413. /*
  414. ******************************************************************************
  415. Name:
  416.     CompressPictF
  417. ------------------------------------------------------------------------------
  418. Purpose:
  419.     ** What it does
  420. ------------------------------------------------------------------------------
  421. Description:
  422.     ** How it does it
  423. ------------------------------------------------------------------------------
  424. Parameters:
  425. ------------------------------------------------------------------------------
  426. When Used:
  427.     ** who calls me and why/when
  428. ******************************************************************************
  429. */
  430. OSErr CompressPictF(ComponentInstance ci, FSSpec *theImageFile)
  431. {
  432.     OSErr                anError;
  433.     short                theFileRefNum;
  434. //    ProgressProcRecord    *progP,progressRec;
  435.  
  436.     /* Set up a progress dialog for display during compression */
  437. // later..
  438. //    progressRec.progressProc = Progress;
  439. //    progressRec.progressRefCon = 0;
  440. //    progP = &progressRec;
  441.  
  442.     /* open the picture file, prepare to compress in place */
  443.     anError = FSpOpenDF(theImageFile, fsRdWrPerm, &theFileRefNum);
  444.  
  445.     /* now compress the picture */
  446.     if (!anError)
  447.     {
  448.         /* Call QuickTime to do its magic.. */
  449.         anError = SCCompressPictureFile(
  450.             ci,
  451.             theFileRefNum,                /* fileRef of source picture file */
  452.             theFileRefNum);                /* fileRef of destination picture file (in place if same as src) */
  453.  
  454.         FSClose(theFileRefNum);
  455.     }
  456.  
  457.     /* force disk update */
  458. //    FlushVol(NULL, theImageFile->vRefNum); -- 5/26/93 [esp] commented out, not needed?
  459.  
  460.     return(anError);
  461. } // CompressPictF
  462.     
  463.     
  464.